
/**
 1、同步执行 + 并发队列       ->: 没有开启新线程，串行执行任务
 2、异步执行 + 并发队列       ->: 有开启新线程，并发执行任务
 
 3、同步执行 + 串行队列       ->: 没有开启新线程，串行执行任务
 4、异步执行 + 串行队列       ->: 有开启新线程(1条)，串行执行任务
 
 5、同步执行 + 主队列        ->: 主线程调用：死锁卡住不执行; 其他线程调用：没有开启新线程，串行执行任务
 6、异步执行 + 主队列        ->: 没有开启新线程，串行执行任务
 */

#import "YDGCDThread.h"

@implementation YDGCDThread {
    // 串行队列的创建方法
    dispatch_queue_t queueSerial;
    // 并发队列的创建方法
    dispatch_queue_t queueConcurrent;
    //信号量 加锁
    dispatch_semaphore_t semaphoreLock;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        //创建串号队列
        queueSerial = dispatch_queue_create("weixin.wuyezhiguhun.SerialQueue", DISPATCH_QUEUE_SERIAL);
        //创建并行队列
        queueConcurrent = dispatch_queue_create("weixin.wuyezhiguhun.ConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
        semaphoreLock = dispatch_semaphore_create(1);
    }
    return self;
}

- (void)setAllQueue {
    // 全局并发队列的获取方法
//    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
//    dispatch_semaphore_t semaphoreLock = dispatch_semaphore_create(1);
}

static YDGCDThread *thread = nil;
+ (instancetype)sharedThread {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        thread = [[YDGCDThread alloc] init];
    });
    return thread;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    if (thread == nil) {
        thread = [super allocWithZone:zone];
    }
    return thread;
}

/**
 * 加锁
 */
- (void)yd_Lock {
    //加锁
    dispatch_semaphore_wait(semaphoreLock, DISPATCH_TIME_FOREVER);
}

/**
 * 解锁
 */
- (void)yd_Unlock {
    //解锁
    dispatch_semaphore_signal(semaphoreLock);
}

/**
 * 添加加锁模块
 * @pram block 加锁内的代码块
 */
+ (void)yd_LockBack:(nullable void (^)(void))block {
    dispatch_semaphore_t semaphoreLock = dispatch_semaphore_create(1);
    //加锁
    dispatch_semaphore_wait(semaphoreLock, DISPATCH_TIME_FOREVER);
    if (block) {
        block();
    }
    //解锁
    dispatch_semaphore_signal(semaphoreLock);
}

/**
 * 添加加锁模块
 * @pram block 加锁内的代码块
 */
- (void)yd_LockBack:(nullable void (^)(void))block {
    //加锁
    dispatch_semaphore_wait(semaphoreLock, DISPATCH_TIME_FOREVER);
    if (block) {
        block();
    }
    //解锁
    dispatch_semaphore_signal(semaphoreLock);
}

/**
 * 创建队列
 * @pram label 字符指针
 * @pram queue 队列类型
 * @return 返回队列
 */
+ (dispatch_queue_t)yd_QueueCreate:(char *)label queue:(YDQueueType)queue {
    if (queue == YDQueueTypeSerial) {
        return dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL);
    } else {
        return dispatch_queue_create(label, DISPATCH_QUEUE_CONCURRENT);
    }
}


/**
 * 创建队列
 * @pram label 字符指针
 * @pram queue 队列类型
 * @return 返回队列
 */
- (dispatch_queue_t)yd_QueueCreate:(char *)label queue:(YDQueueType)queue {
    if (queue == YDQueueTypeSerial) {
        return dispatch_queue_create(label, DISPATCH_QUEUE_SERIAL);
    } else {
        return dispatch_queue_create(label, DISPATCH_QUEUE_CONCURRENT);
    }
}

/**
 * 同步执行 主线程 类方法
 * @pram queue 队列
 * @pram back 回调
 */
+ (void)yd_SyncQueue:(dispatch_queue_t)queue back:(dispatch_block_t)back {
    dispatch_sync(queue, back);
}

/**
 * 异步执行 主线程 类方法
 * @pram back 回调
 */
+ (void)yd_AsyncMainQueueBack:(dispatch_block_t)back {
    dispatch_async(dispatch_get_main_queue(), back);
}

/**
 * 异步执行 自定义线程 类方法
 * @pram queue 队列
 * @pram back 回调
 */
+ (void)yd_AsyncQueue:(dispatch_queue_t)queue back:(dispatch_block_t)back {
    dispatch_async(queue, back);
}

/**
 * 同步执行 自定义线程 对象方法
 * @pram queue 队列
 * @pram back 回调
 */
- (void)yd_SyncQueue:(dispatch_queue_t)queue back:(dispatch_block_t)back {
    dispatch_sync(queue, back);
}

/**
 * 异步执行 主线程 对象方法
 * @pram back 回调
 */
- (void)yd_AsyncMainQueueBack:(dispatch_block_t)back {
    dispatch_async(dispatch_get_main_queue(), back);
}

/**
 * 异步执行 自定义线程 对象方法
 * @pram queue 队列
 * @pram back 回调
 */
- (void)yd_AsyncQueue:(dispatch_queue_t)queue back:(dispatch_block_t)back {
    dispatch_async(queue, back);
}

/**
 * 同步执行 串行 对象方法
 * @pram back 回调
 */
- (void)yd_SyncSerialQueueBack:(dispatch_block_t)back {
    dispatch_sync(queueSerial, back);
}
/**
 * 异步执行 串行 对象方法
 * @pram back 回调
 */
- (void)yd_AsyncSerialQueueBack:(dispatch_block_t)back {
    dispatch_async(queueSerial, back);
}


/**
 * 同步执行 并行 对象方法
 * @pram back 回调
 */
- (void)yd_SyncConcurrentQueueBack:(dispatch_block_t)back {
    dispatch_sync(queueConcurrent, back);
}

/**
 * 异步执行 并行 对象方法
 * @pram back 回调
 */
- (void)yd_AsyncConcurrentQueueBack:(dispatch_block_t)back {
    dispatch_async(queueConcurrent, back);
}

/**
 * 延迟 类方法
 * @pram time 延迟时间
 * @pram back 延迟结束后回调
 */
+ (void)yd_DelayTime:(CGFloat)time back:(dispatch_block_t)back {
    // time 秒后异步追加任务代码到主队列，并开始执行
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), back);
}

/**
 * 延迟 对象方法
 * @pram time 延迟时间
 * @pram back 延迟结束后回调
 */
- (void)yd_DelayTime:(CGFloat)time back:(dispatch_block_t)back {
    // time 秒后异步追加任务代码到主队列，并开始执行
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), back);
}

/**
 * 只执行一次 对象方法
 * @pram back 回调
 */
+ (void)yd_OnceBack:(dispatch_block_t)back {
    static dispatch_once_t onceToken;
    // 只执行1次的代码(这里面默认是线程安全的)
    dispatch_once(&onceToken, back);
}

/**
 * 只执行一次 对象方法
 * @pram back 回调
 */
- (void)yd_OnceBack:(dispatch_block_t)back {
    static dispatch_once_t onceToken;
    // 只执行1次的代码(这里面默认是线程安全的)
    dispatch_once(&onceToken, back);
}

@end
